package com.alfred.java.customannotationaop2.aop;

import com.alfred.java.customannotationaop2.annotation.BaseLog;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

import java.util.Arrays;

@Component
@Aspect
public class LogAspect {

    //抽取公共切入点表达式
    //1 如果是该应用内，只需要@Before("pointCut()")
    //2 如果是其他切面类需要引用，需要写上切面类的路径和方法
    @Pointcut("execution(public int com.alfred.java.customannotationaop2.aop.Calc.*(..))")
    public void pointCut() {
    }

    @Before("execution(public int com.alfred.java.customannotationaop2.aop.Calc.div(int,int))")
    public void logStart(JoinPoint joinPoint) {
        System.out.println("Before 除法运行开始，方法名：" + joinPoint.getSignature().getName() + "  参数列表： {" +
                Arrays.asList(joinPoint.getArgs()) + "}");

    }

    @After("pointCut()")
    public void logEnd() {
        System.out.println("After 除法运行结束。。。。");

    }

    @AfterReturning(value = "com.alfred.java.customannotationaop2.aop.LogAspect.pointCut()", returning = "result")
    public void logReturn(Object result) {
        System.out.println("AfterReturning  除法正常返回，结果为：" + result);

    }

    //测试分母为0的异常情况
    @AfterThrowing(value = "pointCut()", throwing = "exception")
    public void logAfterThrowing(Exception exception) {
        System.out.println("AfterThrowing 除法运算异常 " + exception);

    }

    @Around(value = "pointCut() && @annotation(logAnnotation)  ")
    public Object logAround(ProceedingJoinPoint proceedingJoinPoint, BaseLog logAnnotation) {
        System.out.println("logAround 执行目标方法之前: ");
        try {//这里必须手动调用
            Object obj = proceedingJoinPoint.proceed();
            System.out.println("logAround 目标方法执行之后: ");
            return obj;

        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }

        return -1;

    }
}
